﻿using CipherFactory;
using IR.Common.Utilities;
using IR.Model.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IR.Controller.ModelControllers
{
    public class CUser
    {
        private MUser _currentUser;

        #region **Initializers**
        /// <summary>
        /// New User
        /// </summary>
        public CUser()
        {
            _currentUser = new MUser();
        }

        /// <summary>
        /// For edit screens
        /// </summary>
        /// <param name="cUserToCopy">Push the CUser to copy</param>
        public CUser(CUser cUserToCopy)
        {
            if (cUserToCopy != null)
            {
                _currentUser = new MUser();
                _currentUser.Username = cUserToCopy.Username;
                _currentUser.FName = cUserToCopy.FName;
                _currentUser.LName = cUserToCopy.LName;
                _currentUser.Email = cUserToCopy.Email;
                _currentUser.Password = cUserToCopy.Password;
            }
        }

        /// <summary>
        /// For Login
        /// If user doesn't exit, it will throw an exception
        /// </summary>
        /// <param name="usernameToFind">Enter the username to search for</param>
        /// <param name="passwordToFind">Enter the hased password to search for</param>
        public CUser(string usernameToFind, string passwordToFind)
        {
            MUser tempUser = MUser.Load(usernameToFind);
            if (tempUser != null)
            {
                if (tempUser.Password == passwordToFind)
                {
                    _currentUser = tempUser;
                }
                else
                {
                    Exception NotAValidPassword = new Exception();
                    throw NotAValidPassword;
                }
            }
            else
            {
                Exception NotAValidUserName = new Exception();
                throw NotAValidUserName;
            }
        }

        /// <summary>
        /// For existing Users 
        /// If user doesn't exit, it will throw an exception
        /// </summary>
        /// <param name="usernameToFind">Enter the username to search for</param>
        /// <param name="passwordToFind">Enter the hased password to search for</param>
        public CUser(string usernameToFind)
        {
            MUser tempUser = MUser.Load(usernameToFind);

            if (tempUser != null)
            {
                _currentUser = tempUser;
            }
            else
            {
                if (string.IsNullOrEmpty(usernameToFind))
                {
                    _currentUser = null;
                }
                else
                {
                    Exception NoUserFound = new Exception();
                    throw NoUserFound;
                }
            }
        }

        /// <summary>
        /// Used for Controller constructors
        /// </summary>
        /// <param name="mUserToCopy">Pass in the MUser to copy</param>
        internal CUser(MUser mUserToCopy)
        {
            _currentUser = mUserToCopy;
        }
        #endregion

        #region **Model Relations**
        public string Username
        {
            get
            {
                if (_currentUser == null)
                    return string.Empty;
                return _currentUser.Username;
            }
            set
            {
                if (value != null && value.Length < 51)
                    _currentUser.Username = value;
                else
                    return;
            }
        }

        public string FName
        {
            get { return _currentUser.FName; }
            set
            {
                if (value != null && value.Length < 51)
                    _currentUser.FName = value;
                else
                    return;
            }
        }

        public string LName
        {
            get { return _currentUser.LName; }
            set
            {
                if (value != null && value.Length < 51)
                    _currentUser.LName = value;
                else
                    return;
            }
        }

        public string Email
        {
            get { return _currentUser.Email; }
            set
            {
                if (value != null && value.Length < 51
                    && Validation.IsValidEmail(value) == true)
                    _currentUser.Email = value;
                else
                    return;
            }
        }

        public string Password
        {
            get { return _currentUser.Password; }
            set
            {
                if (value != null && value.Length < 25)
                    _currentUser.Password = StringCipher.Encrypt(value, Settings.GetSetting("cipherpass"));
                else
                    return;
            }
        }
        #endregion

        /// <summary>
        /// Saves the current user
        /// </summary>
        /// <param name="allowOverwrite">Allow editing users</param>
        /// <returns>True if saved</returns>
        public bool Save(bool allowOverwrite = false)
        {
            return _currentUser.Save(allowOverwrite);
        }

        /// <summary>
        /// ***ALWAYS wrap this in a try catch... if it fails it will throw an exceiption***
        /// 
        /// Runs a query on the user table based on a Query you pass in
        /// !!!NOTE: Pass in null to get everything
        /// </summary>
        /// <param name="queries">Dictonary... key = column name, value = value in column</param>
        /// <returns>List of CUsers matching all params, all null param</returns>
        public static List<CUser> QueryUsers(Query queries)
        {
            // Pass in a non-null dictionary
            if (queries == null)
                queries = new Query();

            List<MUser> modelList = MUser.QueryUsers(queries.Queries);

            // Return an empty List if none
            if (modelList == null)
                modelList = new List<MUser>();

            List<CUser> returnList = new List<CUser>(modelList.Count);

            foreach (MUser currentUser in modelList)
            {
                returnList.Add(new CUser(currentUser));
            }

            return returnList;
        }
    }
}